#include <stdint.h>
#include <sys/types.h>
#include <sys/time.h>
#include <unistd.h> 
#include <stdlib.h>
#include <assert.h>
#include "app_platform/cntl_info.h"
#include "organizationdao.h"


#include "c2cplatform/component/dal/dal_set.h"
#include "c2cent/storage/mysqlstorage.h"
#include "c2cplatform/component/dal/db_operator_mysql_set.h"

using namespace c2cplatform::component::dal;
using namespace c2cent::storage;

using namespace erp::organization::dao;

CPP_SELF_DEFINE_START
/**
*  请在这里增加自定义的成员变量和函数及其他内容，否则无法合并代码
**/
#include "organizationdao_enum.h"
#include "erp/comm/erp_macro_define.h"
#include "erp/comm/erp_errno_define.h"

using namespace c2cent::library::wtimeelf;
using namespace c2cent::library::wwlog;
using namespace erp::comm;

CItilGroup COrganizationDao::s_oModifyBranch_Group(MODIFYBRANCH_REQ,MODIFYBRANCH_ERR,MODIFYBRANCH_RSP,MODIFYBRANCH_DEF,TIME_30MS);
CItilGroup COrganizationDao::s_oDeleteBranch_Group(DELETEBRANCH_REQ,DELETEBRANCH_ERR,DELETEBRANCH_RSP,DELETEBRANCH_DEF,TIME_30MS);
CItilGroup COrganizationDao::s_oGetBranch_Group(GETBRANCH_REQ,GETBRANCH_ERR,GETBRANCH_RSP,GETBRANCH_DEF,TIME_30MS);;
CItilGroup COrganizationDao::s_oFindBranch_Group(FINDBRANCH_REQ,FINDBRANCH_ERR,FINDBRANCH_RSP,FINDBRANCH_DEF,TIME_30MS);;
CPP_SELF_DEFINE_END

/**
 *构建函数
 */
COrganizationDao::COrganizationDao(enum DeployMethod method)
{
	m_method=DEPLOY_STANDALONE;
	m_strMachineKey="";
	m_strSource="";
	m_strClientIP="";
	m_dwSceneId=0;
	m_dwOperatorUin=0;
	m_ddwOperatorUid=0;
}

/**
 *析构函数
 */
COrganizationDao::~COrganizationDao()
{
}


/**
 *每一次服务请求时，container都会调用此方法来清空数据
 */
void  COrganizationDao::Reset()
{
	m_strMachineKey="";
	m_strSource="";
	m_strClientIP="";
	m_dwSceneId=0;
	m_dwOperatorUin=0;
	m_ddwOperatorUid=0;
}


int  COrganizationDao::Initialize(IUserDefineCntl* pCntl)
{
	int32_t iRetCode = 0;

	uint32_t dwLogSwitch=WLOG_OPEN|WLOG_KEY_OPEN|WLOG_ERR_OPEN;
	uint32_t dwCanLogRemote = 0;
	std::string strLogModule="dao_organization";

	std::cout<<"File:"<<__FILE__<<" Complie Date: "<<__DATE__<<" "<<__TIME__<<std::endl;

	GetUintConfig(LogSwitch);
	GetStringConfig(LogModule);
	GetUintConfig(CanLogRemote);

	// 初始化日志
	iRetCode=C2C_WWLOG->QuickInitForAPP2(strLogModule.c_str(),B2B2CWW_LOG_APP_FILE_PATH, dwCanLogRemote, dwLogSwitch);
	if(iRetCode!= 0)
	{
		std::cerr << "C2C_WWLOG->QuickInitForAPP2 Failed. RetCode"<<iRetCode << std::endl;
		return iRetCode;
	}
	C2C_WW_LOG("C2C_WWLOG->QuickInitForAPP2 OK!");

	iRetCode=CDAL_SET->Initialize();
	if(iRetCode != 0)
	{
		C2C_WW_LOG_ERR(iRetCode, "CDAL_SET->Initialize Failed");
		return iRetCode;
	}
	return iRetCode;
}


/**
 *
 * 添加/修改分支机构；传入分支机构ID不为0时则进行修改，反之则进行添加；不能进行逻辑删除
 *
 *@param String machineKey: 机器码，必填   [in]
 *@param String source: 调用来源，必填   [in]
 *@param uint32_t sceneId: 场景ID，必填   [in]
 *@param uint32_t option: 功能选项，扩展选填   [in]
 *@param BranchDdo branch: 分支机构PO，必填   [in]
 *@param String inReserve: 请求保留字   [in]
 *@param String errmsg: 错误信息  	[out]
 *@param String outReserve: 返回保留字   	[out]
 *
 *@return  uint32_t : 0(成功) 其它失败
 *
 */
uint32_t COrganizationDao::ModifyBranch(
				const CCntlInfo& rCntlInfo,
				const std::string& strMachineKey,
				const std::string& strSource,
				uint32_t dwSceneId,
				uint32_t dwOption,
				const erp::organization::ddo::CBranchDdo& oBranch,
				const std::string& strInReserve,
				std::string& strErrmsg,
				std::string& strOutReserve
	)
{
	int32_t iRetCode = 0;
	
	iRetCode=_CheckCommParam(rCntlInfo,strMachineKey,strSource,dwSceneId);
	if(iRetCode!=0)
	{
		C2C_WW_LOG_LAST_ERR_LOG(strErrmsg);
		return iRetCode;
	}

    C2C_WW_LOG("GetAReq %s OpUin:%u OpUid:%lu MachineKey:%s Source:%s SceneId:%u", __FUNCTION__,
                    m_dwOperatorUin, m_ddwOperatorUid, strMachineKey.c_str(), strSource.c_str(), dwSceneId);

    //打印性能日志的同时进行接口的itil上报
    C2C_TIME_ELF_ITIL oWTimeElf(C2C_WWLOG,__FUNCTION__,&iRetCode,&s_oModifyBranch_Group);

	return iRetCode;
}

/**
 *
 * 删除分支机构（逻辑）
 *
 *@param String machineKey: 机器码，必填   [in]
 *@param String source: 调用来源，必填   [in]
 *@param uint32_t sceneId: 场景ID，必填   [in]
 *@param uint32_t option: 功能选项，扩展选填   [in]
 *@param Set branchId: 需删除的分支机构的ID，必填   [in]
 *@param String inReserve: 请求保留字   [in]
 *@param String errmsg: 错误信息  	[out]
 *@param Map errorCode: 删除失败的错误码 	[out]
 *@param Map errorMsg: 删除失败的错误信息 	[out]
 *@param String outReserve: 返回保留字   	[out]
 *
 *@return  uint32_t : 0(成功) 其它失败
 *
 */
uint32_t COrganizationDao::DeleteBranch(
				const CCntlInfo& rCntlInfo,
				const std::string& strMachineKey,
				const std::string& strSource,
				uint32_t dwSceneId,
				uint32_t dwOption,
				const std::set<uint64_t >& setBranchId,
				const std::string& strInReserve,
				std::string& strErrmsg,
				std::map<uint64_t,uint32_t >& mapErrorCode,
				std::map<uint64_t,std::string >& mapErrorMsg,
				std::string& strOutReserve
	)
{
	uint32_t dwRet = 0;
	//TODO:业务代码
	
	return dwRet;
}

/**
 *
 * 根据分支机构ID批量获取分支机构信息
 *
 *@param String machineKey: 机器码，必填   [in]
 *@param String source: 调用来源，必填   [in]
 *@param uint32_t sceneId: 场景ID，必填   [in]
 *@param uint32_t option: 功能选项，扩展选填   [in]
 *@param Set branchId: 需获取的分支机构的ID，必填   [in]
 *@param String inReserve: 请求保留字   [in]
 *@param String errmsg: 错误信息  	[out]
 *@param Map errorCode: 获取失败的错误码 	[out]
 *@param Map errorMsg: 获取失败的错误信息 	[out]
 *@param Map branch: 获取成功的分支机构信息 	[out]
 *@param String outReserve: 返回保留字   	[out]
 *
 *@return  uint32_t : 0(成功) 其它失败
 *
 */
uint32_t COrganizationDao::GetBranch(
				const CCntlInfo& rCntlInfo,
				const std::string& strMachineKey,
				const std::string& strSource,
				uint32_t dwSceneId,
				uint32_t dwOption,
				const std::set<uint64_t >& setBranchId,
				const std::string& strInReserve,
				std::string& strErrmsg,
				std::map<uint64_t,uint32_t >& mapErrorCode,
				std::map<uint64_t,std::string >& mapErrorMsg,
				std::map<uint64_t,erp::organization::ddo::CBranchDdo >& mapBranch,
				std::string& strOutReserve
	)
{
	uint32_t dwRet = 0;
	//TODO:业务代码
	
	return dwRet;
}

/**
 *
 * 根据过滤条件查询支机构列表信息
 *
 *@param String machineKey: 机器码，必填   [in]
 *@param String source: 调用来源，必填   [in]
 *@param uint32_t sceneId: 场景ID，必填   [in]
 *@param uint32_t option: 功能选项，扩展选填   [in]
 *@param OrganizationFilterDdo filter: 过滤器，必填   [in]
 *@param String inReserve: 请求保留字   [in]
 *@param String errmsg: 错误信息  	[out]
 *@param uint32_t total: 分支机构总数 	[out]
 *@param Vector branch: 分支机构列表信息 	[out]
 *@param String outReserve: 返回保留字   	[out]
 *
 *@return  uint32_t : 0(成功) 其它失败
 *
 */
uint32_t COrganizationDao::FindBranch(
				const CCntlInfo& rCntlInfo,
				const std::string& strMachineKey,
				const std::string& strSource,
				uint32_t dwSceneId,
				uint32_t dwOption,
				const erp::organization::ddo::COrganizationFilterDdo& oFilter,
				const std::string& strInReserve,
				std::string& strErrmsg,
				uint32_t& dwTotal,
				std::vector<erp::organization::ddo::CBranchDdo >& vecBranch,
				std::string& strOutReserve
	)
{
	uint32_t dwRet = 0;
	//TODO:业务代码
	
	return dwRet;
}

int32_t COrganizationDao::_CheckCommParam(
		const CCntlInfo& rCntlInfo,
		const std::string& strMachineKey,
		const std::string& strSource,
		const uint32_t dwSceneId)
{
	int32_t iRetCode = 0;

	m_strMachineKey=strMachineKey;
	m_strSource=strSource;
	m_dwSceneId=dwSceneId;
	m_dwOperatorUin=rCntlInfo.getOperatorUin();
	m_ddwOperatorUid=rCntlInfo.getOperatorUid();
	IPToString(rCntlInfo.getOperatorClientIP(),m_strClientIP);

	if(m_strMachineKey.empty())
	{
		iRetCode=ERR_ERP_COMMON_MACHINEKEY_INVALID;
	    C2C_WW_LOG_ERR(iRetCode,"MachineKey Error! MachineKey:%s OpUin:%u MachineKey:%s Source:%s SceneId:%u",
	    		m_strMachineKey.c_str(),m_dwOperatorUin, m_strMachineKey.c_str(), m_strSource.c_str(), m_dwSceneId);
		return iRetCode;
	}

	if(m_strSource.empty())
	{
		iRetCode=ERR_ERP_COMMON_SOURCE_INVALID;
	    C2C_WW_LOG_ERR(iRetCode,"Source Error! Source:%s OpUin:%u MachineKey:%s Source:%s SceneId:%u",
	    		m_strSource.c_str(),m_dwOperatorUin, m_strMachineKey.c_str(), m_strSource.c_str(), m_dwSceneId);
		return iRetCode;
	}

	if(m_dwSceneId==0)
	{
		iRetCode=ERR_ERP_COMMON_SCENEID_INVALID;
	    C2C_WW_LOG_ERR(iRetCode,"SceneId Error! SceneId:%u OpUin:%u MachineKey:%s Source:%s SceneId:%u",
	    		m_dwSceneId,m_dwOperatorUin, m_strMachineKey.c_str(), m_strSource.c_str(), m_dwSceneId);
		return iRetCode;
	}

	return iRetCode;
}
